﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Common.MessageHelp;

namespace BoardController.Helper

{

    public static class BytesExtend
    {
        /// <summary>
        /// 拷贝长度
        /// </summary>
        /// <param name="sourceBytes"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public static Byte[] Copy(this Byte[] sourceBytes, int length)
        {
            Byte[] resultBytes = new byte[length];
            Buffer.BlockCopy(sourceBytes, 0, resultBytes, 0, length);
            return resultBytes;
        }

        /// <summary>
        /// 拷贝长度
        /// </summary>
        /// <param name="sourceBytes"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public static Byte[] Copy(this Byte[] sourceBytes, int startIndex, int length)
        {
            Byte[] resultBytes = new byte[length];
            Buffer.BlockCopy(sourceBytes, startIndex, resultBytes, 0, length);
            return resultBytes;
        }

        public static void Copy(this Byte[] sourceBytes, ref Byte[] resultBytes)
        {
            Buffer.BlockCopy(sourceBytes, 0, resultBytes, 0, resultBytes.Length);
        }

        public static Byte[] Mergin(this Byte[] headBytes, ref Byte[] bytes)
        {
            Byte[] resultBytes = new byte[headBytes.Length + bytes.Length];
            Buffer.BlockCopy(headBytes, 0, resultBytes, 0, headBytes.Length);//这种方法仅适用于字节数组
            Buffer.BlockCopy(bytes, 0, resultBytes, headBytes.Length, bytes.Length);
            return resultBytes;
        }
    }


    public class TcpServerHelp
    {
        private Socket m_SocketClient;

        /// <summary>
        /// 服务的IP
        /// </summary>
        private string m_IP;

        /// <summary>
        /// 服务的端口号
        /// </summary>
        private int m_Port;

        private volatile bool m_IsContinue = true;

        // private volatile int m_TestTimes = 0;

        private bool m_IsReceive = true;

        public Action<Byte[]> ReceiveAction;

        private bool m_IsSend = true;

        //  private ConcurrentQueue<Byte[]> m_ReceiveBytesCache = new ConcurrentQueue<byte[]>();

        public TcpServerHelp()
        {

        }

        /// <summary>
        /// 接收发送数据的消息(解决偶尔一次断开连接,直接阻塞,加入队列保证可靠)
        /// </summary>
        /// <param name="tSendMsg"></param>
        public void SendBytes(Byte[] bytes)
        {
            try
            {
                if (m_SocketClient == null)
                {
                    //一会儿重连一下 并记录日志
                  //  LogHelp.AddLog<WarnLogEntity>($"TCP服务器 IP:{m_IP} 端口{m_Port} 发送时Client为空 ");
                    Thread.Sleep(50);
                    SendBytes(bytes);
                    return;
                }

                if (!m_SocketClient.Connected)
                {
                    //重连一下 并记录日志
                   // LogHelp.AddLog<WarnLogEntity>($"TCP服务器 IP:{m_IP} 端口{m_Port} 和Client断开连接 ");
                    Thread.Sleep(50);
                    SendBytes(bytes);
                    return;
                }

                m_SocketClient.Send(bytes);
            }
            catch (Exception e)
            {
                //记录异常日志(这里可能是网线断开了,重连一下,当远程主机强迫关闭一个现有连接)
               // ErrorLogEntity errorLogEntity = new ErrorLogEntity($"TCP服务器 IP:{m_IP} 端口{m_Port} 发生异常");
               // LogHelp.AddLog<ErrorLogEntity>(errorLogEntity);
                Thread.Sleep(50);
                SendBytes(bytes);
            }

        }

        /// <summary>
        /// 单连接
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        public void Init(string ip, int port)
        {
            try
            {
                m_IP = ip;
                m_Port = port;

                IPAddress myIP = IPAddress.Parse(ip);
                IPEndPoint ipEndPoint = new IPEndPoint(myIP, port);
                Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                serverSocket.Bind(ipEndPoint);
                serverSocket.Listen(100000);
                MessageAggregator<PromptMsg>.Publish($"TCP服务器 IP:{m_IP} 端口{m_Port} 初始化成功");
                new Task(() =>
                {
                    //等待连接 建立连接
                    m_SocketClient = serverSocket.Accept();
                    while (true)
                    {
                        try
                        {
                            if (!m_SocketClient.Connected)
                            {
                                //断线重连机制
                                MessageAggregator<PromptMsg>.Publish($"TCP服务器 IP:{m_IP} 端口{m_Port} 断开连接正在尝试重连");
                                m_SocketClient = serverSocket.Accept();
                                MessageAggregator<PromptMsg>.Publish($"TCP服务器 IP:{m_IP} 端口{m_Port} 重连成功");
                            }

                            byte[] receiveBytes = new byte[100000];
                            int length = m_SocketClient.Receive(receiveBytes);
                            if (length == 0)
                            {
                                continue;
                            }
                            if (ReceiveAction == null)
                            {
                                continue;
                            }
                            byte[] realBytes = receiveBytes.Copy(length);
                            ReceiveAction.Invoke(realBytes);


                        }
                        catch (Exception ex)
                        {
                            //ErrorLogEntity errorLogEntity = new ErrorLogEntity($"TCP服务器 IP:{m_IP} 端口{m_Port} 接收数据异常", ex);
                            //LogHelp.AddLog<ErrorLogEntity>(errorLogEntity);
                        }
                    }
                }).Start();
            }
            catch (Exception e)
            {
                //ErrorLogEntity errorLogEntity = new ErrorLogEntity($"TCP服务器 IP:{m_IP} 端口{m_Port} 初始化异常", e);
                //LogHelp.AddLog<ErrorLogEntity>(errorLogEntity);
            }
        }



    }
}
